package com.letv.core.network.volley.toolbox;

import android.content.Context;
import android.text.TextUtils;

import com.letv.core.download.image.DiskLruCache;
import com.letv.core.download.image.DiskLruCache.Snapshot;
import com.letv.core.network.volley.Volley;
import com.letv.core.network.volley.VolleyRequest;
import com.letv.core.network.volley.listener.VolleyCache;
import com.letv.core.utils.FileUtils;
import com.letv.core.utils.MD5;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * 文件缓存
 * 
 * @author zhuqiao
 *
 */
public class VolleyDiskCache implements VolleyCache<String> {
    @SuppressWarnings("unused")
    private Context mContext;
    private DiskLruCache mDiskLruCache;

    /**
     * 缓存文件名.如果为空，那么默认为url地址
     */
    private String mCacheKey;

    public VolleyDiskCache(Context context) {
        this(context, null);
    }

    public VolleyDiskCache(Context context, String cacheKey) {
        mContext = context;
        mCacheKey = cacheKey;
        mDiskLruCache = Volley.getInstance(mContext).getDiskLurCache();
    }

    /**
     * 验证缓存key
     */
    private void checkKey(VolleyRequest<?> request) {
        if (TextUtils.isEmpty(mCacheKey)) {
            if (!TextUtils.isEmpty(request.getUrl())) {
                mCacheKey = MD5.MD5Encode(request.getUrl());
            }
        } else if (mCacheKey.contains("/")) {
            mCacheKey = MD5.MD5Encode(mCacheKey);
        }
    }

    @Override
    public synchronized String get(VolleyRequest<?> request) {
        checkKey(request);
        if (TextUtils.isEmpty(mCacheKey) || mDiskLruCache == null) {
            return FileUtils.getApiFileCache(mContext, mCacheKey);
        }

        Snapshot snapshot = null;
        try {
            snapshot = mDiskLruCache.get(mCacheKey);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        if (snapshot == null) {
            return FileUtils.getApiFileCache(mContext, mCacheKey);
        }

        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;

        try {
            fis = (FileInputStream) snapshot.getInputStream(0);
            if (fis == null) {
                return FileUtils.getApiFileCache(mContext, mCacheKey);
            }

            bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            byte[] data = bos.toByteArray();

            if (data == null)
                return null;

            return new String(data);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bos != null)
                    bos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

            try {
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    public synchronized void add(VolleyRequest<?> request, String data) {
        checkKey(request);
        if (TextUtils.isEmpty(mCacheKey) || TextUtils.isEmpty(data) || mDiskLruCache == null) {
            return;
        }

        try {
            DiskLruCache.Editor editor = mDiskLruCache.edit(mCacheKey);
            if (editor != null) {
                editor.set(0, data);
                editor.commit();
            } else {
                FileUtils.saveApiFileCache(mContext, mCacheKey, data);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public synchronized void remove(VolleyRequest<?> request) {
        checkKey(request);

        if (TextUtils.isEmpty(mCacheKey) || mDiskLruCache == null) {
            return;
        }

        try {
            if (!mDiskLruCache.remove(mCacheKey)) {
                FileUtils.deleteApiFileCache(mContext, mCacheKey);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // FileUtils.deleteApiFileCache(mContext, mCacheKey);
    }

    public synchronized void clear() {
        // FileUtils.deleteAllApiFileCache(mContext);
        if (mDiskLruCache == null) {
            return;
        }

        try {
            mDiskLruCache.delete();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
